package br.com.mtg.movethegarbage.screens;

import javax.microedition.khronos.opengles.GL10;

import android.graphics.RectF;
import android.util.Log;
import br.com.mtg.movethegarbage.framework.Game;
import br.com.mtg.movethegarbage.framework.GameTouchEvent;
import br.com.mtg.movethegarbage.framework.Input;
import br.com.mtg.movethegarbage.framework.Music;
import br.com.mtg.movethegarbage.framework.Screen;
import br.com.mtg.movethegarbage.game.Assets;
import br.com.mtg.movethegarbage.game.GameWorld;
import br.com.mtg.movethegarbage.game.Levels;
import br.com.mtg.movethegarbage.game.Player;
import br.com.mtg.movethegarbage.game.R;
import br.com.mtg.movethegarbage.game.Score;
import br.com.mtg.movethegarbage.graphics.Camera2D;
import br.com.mtg.movethegarbage.graphics.SpriteManager;
import br.com.mtg.movethegarbage.impl.Button;
import br.com.mtg.movethegarbage.impl.ArrowButton;

public class GameScreen extends Screen
{
	GameWorld world;
	Camera2D cam;
	Music music;
	Button right, left, up, down;
	Button exit, resume, restart;
	SpriteManager spriteManager;
	Score score;
	boolean pause;
	boolean gameWin;
	int mapLevel;
	float beginX, beginY;
	int touchId;

	int fps;
	long counter = 0;

	public GameScreen(Game _game, int _map)
	{
		super(_game);

		cam = new Camera2D(game.getGraphics());
		width = game.getGraphics().getWidth();
		height = game.getGraphics().getHeight();
		multiplier = game.getGraphics().getMultiplier();
		spriteManager = new SpriteManager(game.getGraphics(), 1);
		mapLevel = _map;

		Assets.font.setScale(1.0F * multiplier);

		right = new ArrowButton(width - 50 * multiplier, (height - 50 * multiplier) / 2, 50 * multiplier, 50 * multiplier, ArrowButton.DIRECTION_RIGHT);
		left = new ArrowButton(0, (height - 50 * multiplier) / 2, 50 * multiplier, 50 * multiplier, ArrowButton.DIRECTION_LEFT);
		up = new ArrowButton((width - 50 * multiplier) / 2, height - 50 * multiplier, 50 * multiplier, 50 * multiplier, ArrowButton.DIRECTION_UP);
		down = new ArrowButton((width - 50 * multiplier) / 2, 0, 50 * multiplier, 50 * multiplier, ArrowButton.DIRECTION_DOWN);

		right.setButtonSprite(Assets.buttonArrowGray);
		left.setButtonSprite(Assets.buttonArrowGray);
		up.setButtonSprite(Assets.buttonArrowGray);
		down.setButtonSprite(Assets.buttonArrowGray);

		float stringWidth = Assets.font.getTextLength(game.getStringFromResource(R.string.resume));
		resume = new Button((width - stringWidth - 20) / 2, (height) / 2, game.getStringFromResource(R.string.resume), 1.0F * multiplier,
				Assets.buttonBackgroundRect);

		stringWidth = Assets.font.getTextLength(game.getStringFromResource(R.string.exit));
		exit = new Button((width - stringWidth - 20) / 2, (height) / 2 - 20 * multiplier - Assets.font.getTextHeight(),
				game.getStringFromResource(R.string.exit), 1.0F * multiplier, Assets.buttonBackgroundRect);

		stringWidth = Assets.font.getTextLength(game.getStringFromResource(R.string.restart));
		restart = new Button((width - stringWidth - 20) / 2, (height) / 2 + 20 * multiplier + Assets.font.getTextHeight(),
				game.getStringFromResource(R.string.restart), 1.0F * multiplier, Assets.buttonBackgroundRect);

		pause = false;

		world = new GameWorld(game, Levels.getMap(mapLevel));
		world.loadAndInitializeMap();
		gameWin = false;
		beginX = 0;
		beginY = 0;
		touchId = -1;
	}

	@Override
	public void update(long delta)
	{

		if (counter >= 1000)
		{
			if (delta > 0)
				fps = game.getFPS().fps(delta);
			counter = 0;
		}
		counter += delta;

		Input input = game.getInput();
		RectF rect = new RectF(50 * multiplier, height - 50 * multiplier, width - 50 * multiplier, 50 * multiplier);
		rect.sort();
		synchronized (input)
		{
			for (GameTouchEvent e : input.getTouchEvents())
			{
				if (!pause && !gameWin)
				{
					if (rect.contains(e.touchX, e.touchY))
					{
						if (e.type == GameTouchEvent.TOUCH_DOWN)
						{
							touchId = e.pointerID;
							beginX = e.touchX;
							beginY = e.touchY;
						}
					}

					if (e.type == GameTouchEvent.TOUCH_UP && e.pointerID == touchId)
					{
						float deltaX = e.touchX - beginX, deltaY = e.touchY - beginY;
						if (Math.abs(deltaX) > 30 * multiplier)
						{
							if (deltaX > 0)
								world.movePlayer(Player.DIRECTION_RIGHT);
							else if (deltaX < 0)
								world.movePlayer(Player.DIRECTION_LEFT);
						}
						else if (Math.abs(deltaY) > 30 * multiplier)
						{
							if (deltaY > 0)
								world.movePlayer(Player.DIRECTION_UP);
							else if (deltaY < 0)
								world.movePlayer(Player.DIRECTION_DOWN);
						}
						touchId = -1;
					}

					right.handleEvent(e, game);
					left.handleEvent(e, game);
					up.handleEvent(e, game);
					down.handleEvent(e, game);
				}
				else
				{
					resume.handleEvent(e, game);
					exit.handleEvent(e, game);
					if (!gameWin)
						restart.handleEvent(e, game);
				}
			}
			input.getTouchEvents().clear();
		}
		if (pause || gameWin)
		{
			if (resume.wasPressed())
			{
				if (gameWin)
				{
					try
					{
						if (game.loadProgress() == mapLevel)
							game.saveProgress(mapLevel + 1);
					}
					catch (Exception e)
					{
						Log.e("GameScreen", "Error saving progress");
					}
					game.setScreen(new SaveScoreScreen(game, world.getGameScore(), mapLevel));
				}
				else
					pause = false;
			}
			else if (exit.wasPressed() || input.wasBackPressed())
			{
				if (gameWin)
				{
					try
					{
						if (game.loadProgress() == mapLevel)
							game.saveProgress(mapLevel + 1);
					}
					catch (Exception e)
					{
						Log.e("GameScreen", "Error saving progress");
					}
				}
				game.setScreen(new MapScreen(game));
			}
			else if (restart.wasPressed())
			{
				world = new GameWorld(game, Levels.getMap(mapLevel));
				world.loadAndInitializeMap();
				pause = false;
			}
		}
		else
		{
			if (input.wasBackPressed())
				pause = true;
			else if (right.wasPressed())
				world.movePlayer(Player.DIRECTION_RIGHT);
			else if (left.wasPressed())
				world.movePlayer(Player.DIRECTION_LEFT);
			else if (up.wasPressed())
				world.movePlayer(Player.DIRECTION_UP);
			else if (down.wasPressed())
				world.movePlayer(Player.DIRECTION_DOWN);
		}

		gameWin = world.update();
	}

	@Override
	public void present(long delta)
	{
		game.getGraphics().getGL().glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
		if (gameWin)
		{
			spriteManager.beginDraw(Assets.tex_backgroundScreenRedMain);
			spriteManager.drawSprite(0, 0, width, height, Assets.background);
			spriteManager.endDraw();

			Assets.font.setScale(0.7F * multiplier);
			float stringWidth = Assets.font.getTextLength(game.getStringFromResource(R.string.win));
			Assets.font.printAt(game.getStringFromResource(R.string.win), (width - stringWidth) / 2, height - Assets.font.getTextHeight());

			resume.draw(game.getGraphics());
			exit.draw(game.getGraphics());
		}
		else if (pause)
		{
			spriteManager.beginDraw(Assets.tex_backgroundScreenRedMain);
			spriteManager.drawSprite(0, 0, width, height, Assets.background);
			spriteManager.endDraw();

			resume.draw(game.getGraphics());
			exit.draw(game.getGraphics());
			restart.draw(game.getGraphics());
		}
		else
		{
			world.draw(game.getGraphics());
			right.draw(game.getGraphics());
			left.draw(game.getGraphics());
			up.draw(game.getGraphics());
			down.draw(game.getGraphics());
		}
		Assets.font.setScale(0.5F * multiplier);
		Assets.font.printAt(Integer.toString(fps), 0, 0);
	}

	@Override
	public void pause()
	{
		if (game.getAudio().soundEnabled)
			music.pause();
		pause = true;
	}

	@Override
	public void resume()
	{
		if (game.getAudio().soundEnabled)
		{
			if (music == null)
			{
				Assets.music1.stop();

				if (System.currentTimeMillis() % 3 == 0)
					music = Assets.music2;
				else
					music = Assets.music3;
			}

			music.play();
			music.setLooping(true);
			music.setVolume(1.0F);
		}

		cam.setViewAndMatrices();

		game.getGraphics().initialize();

		game.getGraphics().getGL().glClearColor(0.0F, 0.0F, 0.0F, 1.0F);

		width = game.getGraphics().getWidth();
		height = game.getGraphics().getHeight();
		multiplier = game.getGraphics().getMultiplier();

	}

	@Override
	public void dispose()
	{
		if (game.getAudio().soundEnabled)
			music.stop();
	}

}
